码妞:Java的一堆锁是干嘛的?能锁住体重吗?
作者:iMononoke
博客:https://juejin.im/user/5c629a3051882562191755d8
上次就说会被码妞“烦”了,果然她来了……
各种锁
dangdangdang~
来慢慢讲~
1. 悲观 Vs 乐观
看下它们的流程:
它们的区别~
2. 公平 Vs 非公平
公平锁和非公平锁的示例:
公平锁就是新来的线程乖乖排到队列最后去等待着~
非公平锁就是新来的线程先试着插队能不能成功(获取到锁),成功的话,就在当前运行的线程执行完成后就拿到锁了,开始它的执行过程;
如果插队失败,就和公平锁的流程一样,排到队伍最后去了。
3. 可重入 Vs 不可重入
下面我们来看可重入锁和不可重入锁~
ReentrantLock
和synchronized
都是可重入锁~
可重入锁的栗子:
当一个线程执行到某个synchronized方法时,
比如说method1,在method1中又会调用另外一个synchronized方法method2,
此时线程不必重新去申请锁,而是可以直接执行方法method2。
看下面这段代码就知道了:
class MyClass {
public synchronized void method1() {
doSth();
}
public synchronized void method2() {
doAnother();
}
}
如果不是可重入锁的话,method2可能不会被当前线程执行,可能造成死锁。
不可重入锁的栗子
用自旋锁来模拟,代码如下:
public class UnreentrantLock {
private AtomicReference<Thread> owner = new AtomicReference<Thread>();
public void lock() {
Thread current = Thread.currentThread();
//这句是很经典的“自旋”语法,AtomicInteger中也有
for (;;) {
if (!owner.compareAndSet(null, current)) {
return;
}
}
}
public void unlock() {
Thread current = Thread.currentThread();
owner.compareAndSet(current, null);
}
}
同一线程两次调用lock()方法,如果不执行unlock()释放锁的话,第二次调用自旋的时候就会产生死锁。
有个叫midnight的小伙伴说,可重入锁就好比,“你跟一个妹子谈恋爱,结果分手了,后来你又想谈恋爱了,你又找到那个妹子,那个妹子也还没男朋友,你们就可以减少繁琐的自我介绍等等环节直接牵手了。”
以上观点不代表码仔想法,码仔也不表示赞同,谢谢~
近期文章:
今日问题:
想听码仔讲哪些Java芝士点?
快来码仔社群解锁新姿势吧!社群升级:Max你的学习效率